package com.zidian.leader.api;

import android.support.annotation.Nullable;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.zidian.leader.common.util.StringConstants;
import com.zidian.leader.entity.ColleagueEvaResult;
import com.zidian.leader.entity.ColleagueEvaTwoIndex;
import com.zidian.leader.entity.EvaluateRate;
import com.zidian.leader.entity.EvaluateRateCollege;
import com.zidian.leader.entity.HttpResult;
import com.zidian.leader.entity.LoginResult;
import com.zidian.leader.entity.NoDataResult;
import com.zidian.leader.entity.QuestionnaireDetail;
import com.zidian.leader.entity.StudentEvaSummary;
import com.zidian.leader.entity.StudentEvaTwoIndex;
import com.zidian.leader.entity.StudentStatistics;
import com.zidian.leader.entity.StudentStatisticsCollege;

import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

/**
 * Created by GongCheng on 2016/11/2.
 */

public class HttpFactory {
    private Retrofit retrofit;
    private LeaderService leaderService;

    /**
     * 构造方法私有
     */
    private HttpFactory() {
        //拦截器
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                Log.i("HTTP:", message);
            }
        });
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        //创建OKHttpClient
        OkHttpClient client = new OkHttpClient.Builder()
                .addNetworkInterceptor(logging)
                .connectTimeout(Constant.DEFAULT_TIME_OUT, TimeUnit.SECONDS)
                .build();
        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd HH:mm:ss")
                .setLenient()
                .create();
        //创建Retrofit
        retrofit = new Retrofit.Builder()
                .client(client)
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .baseUrl(Constant.URL_LEADER)
                .build();
        leaderService = retrofit.create(LeaderService.class);
    }

    /**
     * 访问HttpFactory是创建单例
     */
    private static class SingletonHolder {
        private static final HttpFactory INSTANCE = new HttpFactory();
    }

    /**
     * 获取单例
     */
    public static HttpFactory getInstance() {
        return SingletonHolder.INSTANCE;
    }

    /**
     * 线程切换
     *
     * @param o   observable
     * @param <T> T
     * @return
     */
    private <T> Observable<T> toSubscribe(Observable<T> o) {
        return o.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }


    /**
     * 用户登录
     *
     * @param username 用户名
     * @param password 密码
     * @return Subscription
     */
    public Observable<LoginResult> login(String username, String password) {
        Observable<LoginResult> observable = leaderService.login(username, password)
                .map(new Func1<LoginResult, LoginResult>() {
                    @Override
                    public LoginResult call(LoginResult loginResult) {
                        if (loginResult.getCode() != 200) {
                            throw new ApiException(loginResult.getMessage());
                        }
                        return loginResult;
                    }
                });

        return toSubscribe(observable);
    }

    /**
     * 学生统计(全校)
     *
     * @param leadId
     * @param college
     * @param roleId
     * @param token
     * @return
     */
    public Observable<StudentStatistics> getStudentStatistics(
            String leadId, String college, String roleId, String token) {
        Observable<StudentStatistics> observable = leaderService.getStudentStatistics(leadId, college
                , roleId, token).map(new HttpResultFunc<StudentStatistics>());
        return toSubscribe(observable);
    }

    /**
     * 学生统计(院系)
     *
     * @param leadId
     * @param college
     * @param roleId
     * @param token
     * @return
     */
    public Observable<List<StudentStatisticsCollege>> getStudentStatisticsCollege(
            String leadId, String college, String roleId, String token) {
        Observable<List<StudentStatisticsCollege>> observable = leaderService.getStudentStatisticsCollege(
                leadId, college, roleId, token)
                .map(new HttpResultFunc<List<StudentStatisticsCollege>>());
        return toSubscribe(observable);
    }

    /**
     * 教评完成率（全校）
     *
     * @param teacherId
     * @param roleId
     * @param token
     * @return
     */
    public Observable<HttpResult<List<EvaluateRate>>> getEvaluateRate(
            String teacherId, String roleId, String token) {
        return leaderService.getEvaluateRate(StringConstants.STRING_EMPTY,
                StringConstants.STRING_EMPTY, teacherId, roleId, token);
    }

    /**
     * 得到评教完成率（院系）
     *
     * @param collegeName
     * @param teacherId
     * @param roleId
     * @param token
     * @return
     */
    public Observable<HttpResult<List<EvaluateRateCollege>>> getEvaluateRateCollege(
            String collegeName, String teacherId, String roleId, String token) {
        return leaderService.getEvaluateRateCollege(StringConstants.STRING_EMPTY,
                collegeName, teacherId, roleId, token);
    }

    /**
     * 问卷详情
     *
     * @param teacherId
     * @param questionnaireExplain
     * @param roleId
     * @param token
     * @return
     */
    public Observable<List<QuestionnaireDetail>> getQuestionnaireDetail(
            String teacherId, String questionnaireExplain, String roleId, String token) {
        Observable<List<QuestionnaireDetail>> observable = leaderService.getQuestionnaireDetail(
                teacherId, questionnaireExplain, roleId, token)
                .map(new HttpResultFunc<List<QuestionnaireDetail>>());

        return toSubscribe(observable);
    }

    /**
     * 学生评价概要
     *
     * @param collegeName
     * @param teacherId
     * @param roleId
     * @param token
     * @return
     */
    public Observable<List<StudentEvaSummary>> getStudentEvaSummary(
            @Nullable String collegeName, String teacherId, String roleId, String token) {
        Observable<List<StudentEvaSummary>> observable = leaderService.getStudentEvaSummary(
                collegeName, teacherId, roleId, token)
                .map(new HttpResultFunc<List<StudentEvaSummary>>());
        return toSubscribe(observable);
    }


    /**
     * 督导/同行评价概要
     *
     * @param statisticsType
     * @param collegeName
     * @param teacherId
     * @param roleId
     * @param token
     * @return
     */
    public Observable<ColleagueEvaResult> getColleagueEvaSummary(
            String statisticsType, @Nullable String collegeName, String teacherId, String roleId, String token) {

        return leaderService.getColleagueEva(statisticsType, collegeName, teacherId, roleId, token);

    }

    public Observable<String> getColleagueEva(
            String statisticsType, @Nullable String collegeName, String teacherId, String roleId, String token) {

        return leaderService.getColleagueEvaSummary(statisticsType, collegeName, teacherId, roleId, token);
    }

    /**
     * 学生评价二级标签
     *
     * @param collegeName
     * @param twoIndexName
     * @param teacherId
     * @param roleId
     * @param token
     * @return
     */
    public Observable<List<StudentEvaTwoIndex>> getStudentEvaTwoIndex(
            @Nullable String collegeName, String twoIndexName, String teacherId, String roleId, String token) {
        Observable<List<StudentEvaTwoIndex>> observable = leaderService.getStudentEvaTwoIndex(
                collegeName, twoIndexName, teacherId, roleId, token)
                .map(new HttpResultFunc<List<StudentEvaTwoIndex>>());
        return toSubscribe(observable);
    }

    /**
     * 得到督导/同行评价二级标签
     *
     * @param collegeName
     * @param statisticsType
     * @param indexName
     * @param teacherId
     * @param roleId
     * @param token
     * @return
     */
    public Observable<ColleagueEvaTwoIndex> getColleagueEvaTwoIndex(
            @Nullable String collegeName, String statisticsType, String indexName,
            String teacherId, String roleId, String token) {
        Observable<ColleagueEvaTwoIndex> observable = leaderService.getColleagueEvaTwoIndex(
                collegeName, statisticsType, indexName, teacherId, roleId, token)
                .map(new HttpResultFunc<ColleagueEvaTwoIndex>());
        return toSubscribe(observable);
    }

    /**
     * 修改密码
     *
     * @param teacherId
     * @param password
     * @param password1
     * @param password2
     * @param roleId
     * @param token
     * @return
     */
    public Observable<NoDataResult> changePassword(
            String teacherId, String password, String password1,
            String password2, String roleId, String token) {
        return leaderService.changePassword(teacherId, password, password1, password2, roleId, token);
    }

}
